﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.IO;

namespace DotNETX.FileServer
{
    /// <summary>
    /// 服务端文件管理
    /// </summary>
    [ServiceContract(SessionMode = SessionMode.Required)]
    [ServiceKnownType(typeof(RemoteFileInfo))]
    [ServiceKnownType(typeof(FileSectionInfo))]
    public interface IFileManagerService
    {
        [OperationContract]
        bool HasFile(string vPath);

        [OperationContract]
        List<string> GetDirs(string vPath);

        [OperationContract]
        List<RemoteFileInfo> GetFiles(string vPath);

        [OperationContract]
        RemoteFileInfo GetFile(string vFile);

        [OperationContract]
        FileSectionInfo GetFileSection(string vFile, long offset, int length);

        /// <summary>
        /// 
        /// </summary>
        /// <param name="rFile"></param>
        /// <returns>
        /// 文件句柄
        /// </returns>
        [OperationContract]
        [FaultContract(typeof(FileErrorCode))]
        string PutFile(RemoteFileInfo rFile, bool cover);

        /// <summary>
        /// 
        /// </summary>
        /// <param name="handle">文件句柄</param>
        /// <param name="section"></param>
        /// <returns>
        /// 成功存储字节数
        /// </returns>
        [OperationContract]
        [FaultContract(typeof(FileErrorCode))]
        int PutFileSection(string handle, FileSectionInfo section);

        [OperationContract]
        bool CancelPutFile(string handle);

        [OperationContract]
        [FaultContract(typeof(FileErrorCode))]
        bool DeleteFile(string vFile);

        [OperationContract]
        [FaultContract(typeof(FileErrorCode))]
        bool CopyFile(string vFile, string vNewFile, bool cover);

        [OperationContract]
        [FaultContract(typeof(FileErrorCode))]
        bool MoveFile(string vFile, string vNewFile, bool cover);
    }

    [DataContract]
    public class RemoteFileInfo
    {
        [DataMember]
        public string VirtualPath { get; set; }
        [DataMember]
        public long Length { get; set; }
    }

    [DataContract]
    public class FileSectionInfo
    {
        [DataMember]
        public long TotalLength { get; set; }

        [DataMember]
        public long Offset { get; set; }

        [DataMember]
        public int ContentLength { get; set; }

        [DataMember]
        public byte[] Content { get; set; }

        //[DataMember]
        //public Stream Stream { get; set; }
    }

    public enum FileErrorCode
    {
        FileNotExist = 0,
        PathNotExist,
        FileHandleNotExist,
        FileExist,
        Unknow
    }

    public class FileCompleteInfo
    {
        public string VirtualPath { get; set; }
        public string FilePath { get; set; }
        public long TotalLength { get; set; }
        public long CompleteLength { get; set; }
        public bool IsCover { get; set; }
        public bool IsCancel { get; set; }
    }
}
